Nome: Federico
Cognome: Signoretta
Numero matricola: 847343
E-mail: f.signoretta@campus.unimib.it
A.A. 2019-2020

Digital Signal and Image Management

  • Docente: Simone Bianco
  • Docente: Marco Buzzelli
  • Esercitatore: Simone Zini

Assignment n.2

Descrizione: implementare la funzione di sharpening per esaltare i dettagli di un'immagine in scala di grigi tramite unsharp mask, partendo dalle istruzioni viste ad esercitazione. Verificare l'effetto di diversi parametri coinvolti nelle operazioni utilizzate.

1. Import dei pacchetti

In [391]:
import numpy as np

# Gestione immagini
from skimage import io # Per input/output
from skimage import transform # Per trasformazioni geometriche (es. resize)
from skimage import filters # Per filtri locali
from skimage import color # Per cambi colore

# Visualizzazione e interazione
from matplotlib import pyplot as plt
import ipywidgets as widgets

import seaborn as sns
# Imposta le dimensioni di visualizzazione nel notebook
#plt.rcParams['figure.figsize'] = [15,5] # width, height

2. Caricamento e visualizzazione immagine

2.1 Immagine caricata in RGB

In [392]:
img_rgb = io.imread('lena.jpg')
In [393]:
# Visualizzazione canali R,G,B con mappe colore
plt.subplot(1,3,1)
plt.imshow(img_rgb[:,:,0], cmap='Reds')
plt.title('Red')
plt.subplot(1,3,2)
plt.imshow(img_rgb[:,:,1], cmap='Greens')
plt.title('Green')
plt.subplot(1,3,3)
plt.imshow(img_rgb[:,:,2], cmap='Blues')
plt.title('Blue')
plt.show()


kwargs = dict(hist_kws={'alpha':.3}, kde_kws={'linewidth':2})

plt.figure()
sns.distplot(img_rgb[:, :, 0].ravel(), color="red", label="Red", **kwargs)
sns.distplot(img_rgb[:, :, 1].ravel(), color="green", label="Green", **kwargs)
sns.distplot(img_rgb[:, :, 2].ravel(), color="blue", label="Blue", **kwargs)

plt.xlabel('Value')
plt.title('Density plot')
plt.show()
In [394]:
# Dimensioni immagine
print('La dimensione dell\'immagine in RGB è:', img_rgb.shape[0],'x',img_rgb.shape[1],'x',img_rgb.shape[2])
La dimensione dell'immagine in RGB è: 400 x 400 x 3

2.2 Immagine caricata in scala di grigi

L'immagine viene caricata in scala di grigi, ossia la scala è ottenuta come combinazione lineare dei tre canali di colori Red, Green e Blue (RGB).

In [395]:
# Funzione per la rappresentazione dell'immagine e del relativo histogramma
def plot_fig_hist(img, type_img):
    
    fig = plt.figure(figsize=(16,6))

    fig.add_subplot(1,2,1)
    plt.imshow(img, cmap='gray')
    plt.title(str(type_img))
    #plt.colorbar()

    fig.add_subplot(1,2,2)
    kwargs = dict(hist_kws={'alpha':.3}, kde_kws={'linewidth':2})

    sns.distplot(img.ravel(), color="gray", label="grayscale", **kwargs)

    plt.xlabel('Value')
    plt.ylabel('Density')
    plt.title('Density plot - '+str(type_img))
    plt.show()
In [396]:
original_img = io.imread('lena.jpg', as_gray=True)
plot_fig_hist(original_img, 'Original')
In [397]:
# Dimensioni immagine
print('La dimensione dell\'immagine in scala di grigi è', original_img.shape[0],'x',original_img.shape[1])
La dimensione dell'immagine in scala di grigi è 400 x 400

3. Sharpening

Passaggi consigliati per filtro di sharpening:

  1. Filtraggio gaussiano per sfocare l'immagine (eliminare i dettagli), ossia sfuocare l’immagine originale $$I_{blurred}= G_{\sigma}(I_{original})$$ dove $G_{\sigma}(\cdot)$ è la funzione filtro gaussiano

  2. Differenza tra immagine originale e filtrata per isolare i dettagli, quindi ottenere la maschera come differenza tra l’immagine originale e la copia sfuocata $$I_{diff}= I_{original} - I_{blurred}$$
  3. Somma dei dettagli all'originale per esaltarli, quindi aggiungere la maschera all’immagine originale $$I_{enhanced}= I_{original} + k I_{diff}$$ dove $k$ è una costante, solitamente pari a 1

3.1 Filtraggio gaussiano

In [414]:
blurred_img = filters.gaussian(original_img, sigma=50, preserve_range=True)
plot_fig_hist(blurred_img, 'Blurred')

3.2 Isolamento dettagli

Viene fatta la differenza tra l'immagine originale e quella filtrata

In [415]:
diff_img = original_img - blurred_img
plot_fig_hist(diff_img, 'Difference')

3.3 Aggiunta della maschera all'originale

Viene sommata l'immagine ottenuta come differenza tra l'immagine originale e quella filtrata (ottenuta nel punto 3.2) all'immagine originale.

La scelta del valore $k$, dipende da quanto peso si vuole dare alla maschera ootenuta precedentemente.
Partiamo con $$k=1$$

In [416]:
enhanced_img = original_img + diff_img
enhanced_img = np.where(enhanced_img<0, 0, enhanced_img)
enhanced_img = np.where(enhanced_img>1, 1, enhanced_img)
plot_fig_hist(enhanced_img, 'Enhanced')

Ora, per dare maggiore peso alla maschera, verrà utilizzata $$k=3$$

In [401]:
enhanced_img_k3 = original_img + 3*diff_img
enhanced_img_k3 = np.where(enhanced_img_k3<0, 0, enhanced_img_k3)
enhanced_img_k3 = np.where(enhanced_img_k3>1, 1, enhanced_img_k3)
plot_fig_hist(enhanced_img_k3, 'Enhanced')

Dando maggiore peso alla maschera è possibile notare immediatamente che vi è un aumento esagerato dei dettagli, provocando un aumento del rumore generale dell'immagine. Pertanto, d'ora in poi verrà utilizzato un valore di $k$ pari a 1.

3.4 Confronto tra immagine originale e enhanced

$$k=1$$
In [402]:
fig = plt.figure(figsize=(16,6))

fig.add_subplot(1,2,1)
plt.imshow(original_img, cmap='gray')
plt.title('Original')
#plt.colorbar()

fig.add_subplot(1,2,2)
plt.imshow(enhanced_img, cmap='gray')
plt.title('Enhanced')
plt.show()

4. Confronto tra le immagini utilizzando diversi valori di $\sigma$ nella fase di filtraggio

In [403]:
# funzione per la rappresentazione grafica dei 3 step della funzione sharpening
def sharp_effect(img, sigma):
    #1.filtraggio con gauss
    blurr_ = filters.gaussian(img, sigma=sigma,preserve_range=True)
    #2. differenza tra originale e filtrata
    diff_= img - blurr_
    #3. somma della differenza con originale
    enhan_ = img + diff_
    enhan_ = np.where(enhan_<0, 0, enhan_)
    enhan_ = np.where(enhan_>1, 1, enhan_)
    
    #images
    fig = plt.figure(figsize=(18,9))
    
    fig.add_subplot(2,4,1)
    plt.imshow(img, cmap='gray')
    plt.title('Original')
 #   plt.title('Original - sigma=' + str(sigma))
    plt.axis('off')

    fig.add_subplot(2,4,2)
    plt.imshow(blurr_, cmap='gray')
    plt.title('Blurred')
    plt.axis('off')

    fig.add_subplot(2,4,3)
    plt.imshow(diff_, cmap='gray')
    plt.title('Difference')
    plt.axis('off')

    fig.add_subplot(2,4,4)
    plt.imshow(enhan_, cmap='gray')
    plt.title('Enhanced')
    plt.axis('off')

    #density plot
    kwargs = dict(hist_kws={'alpha':.3}, kde_kws={'linewidth':2})
    
    fig.add_subplot(2,4,5)
    sns.distplot(img.ravel(), color="gray", label="grayscale", **kwargs)
#    plt.xlabel('Value')
 #   plt.title('Original - sigma=' + str(sigma))

    fig.add_subplot(2,4,6)
    sns.distplot(blurr_.ravel(), color="gray", label="grayscale", **kwargs)
#    plt.xlabel('Value')
 #   plt.title('Blurred')
#    plt.title('Blurred - sigma=' + str(sigma))

    fig.add_subplot(2,4,7)
    sns.distplot(diff_.ravel(), color="gray", label="grayscale", **kwargs)
 #   plt.xlabel('Value')
#    plt.title('Difference')
 #   plt.title('Difference - sigma='+ str(sigma))

    fig.add_subplot(2,4,8)
    sns.distplot(enhan_.ravel(), color="gray", label="grayscale", **kwargs)
 #   plt.xlabel('Value')
 #   plt.title('Enhanced')
  #  plt.title('Enhanced - sigma='+ str(sigma))

    fig.suptitle('sigma='+ str(sigma))
    
    plt.show()

4.1 Filtraggio con $\sigma=0.5$

In [404]:
sharp_effect(original_img, sigma=0.5)

4.2 Filtraggio con $\sigma=1.5$

In [405]:
sharp_effect(original_img, sigma=1.5)

4.3 Filtraggio con $\sigma=5$

In [406]:
sharp_effect(original_img, sigma=5)

4.4 Filtraggio con $\sigma=20$

In [407]:
sharp_effect(original_img, sigma=20)

4.5 Filtraggio con $\sigma=50$

In [408]:
sharp_effect(original_img, sigma=50)

5. Conclusioni

Lo scopo dei filtri di sharpening è di incrementare la nitidezza di una immagine aumentando il contrasto locale. Dalle prove effettuate nel punto 4, è evidente che utilizzando valori elevati di $\sigma$, si ottengono delle immagini apparetemente più nitide, ma con la presenza di maggiore rumore. Viceversa, utilizzando valori di $\sigma<1$, l'immagine appare essere molto simile all'originale. Dunque, la scelta di $\sigma$ risulta essere fondamentale per aumentare la nitidezza dell'immagine, ma se tale valore è troppo elevato potrebbe creare del rumore ed uno spostamento eccessivo della curva di denistà verso gli scuri.